<?php
class LRDDXRD {
    
    private $links;
    private $subject;
    
    const KEY_MAGIC_PUBLIC_KEY = "magic-public-key";
    const KEY_UPDATES_FROM     = "http://schemas.google.com/g/2010#updates-from";
    const KEY_SALMON_REPLIES   = "http://salmon-protocol.org/ns/salmon-replies";
    const KEY_SALMON_MENTION   = "http://salmon-protocol.org/ns/salmon-mention";
    
    public function __construct($subject, Array $links = array()) {
        $this->setSubject($subject);
        $this->setLinks($links);
    }
    
    private function setSubject($subject) {
        if(empty($subject)) {
            Throw new Exception("Subject cannot be set empty.");
        }
       $this->subject = $subject;
    }
    
    private function setLinks(Array $links) {
       $this->links = $links;
    }
    
    public function getLinks() {
        return $this->links;
    }
    
    public function getLinkUpdatesFrom() {
        return $this->getLinkWithKey(self::KEY_UPDATES_FROM);
    }
    
    public function getLinkSalmonReplies() {
        return $this->getLinkWithKey(self::KEY_SALMON_REPLIES);
    }
    
    public function getLinkMagicPublicKey() {
        return $this->getLinkWithKey(self::KEY_MAGIC_PUBLIC_KEY);
    }
    
    private function getLinkWithKey($key) {
        if(is_array($this->links[$key])) {
            return $this->links[$key];
        }
        return array();
    }
    
	/**
     * Builind funrgion will try to create HostMetaXRD object from XML.
     * 
     * Example XML expected:
     * <?xml version="1.0" encoding="UTF-8"?>
	 * <XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
  	 *    <Subject>acct:tkoski@identi.ca</Subject>
  	 *    <Alias>http://identi.ca/user/52467</Alias>
  	 *    <Link rel="http://webfinger.net/rel/profile-page" type="text/html" href="http://identi.ca/user/52467"/>
  	 *    <Link rel="http://schemas.google.com/g/2010#updates-from" type="application/atom+xml" href="http://identi.ca/api/statuses/user_timeline/52467.atom"/>
  	 *    <Link rel="http://microformats.org/profile/hcard" type="text/html" href="http://identi.ca/tkoski/hcard"/>
  	 *    <Link rel="http://gmpg.org/xfn/11" type="text/html" href="http://identi.ca/user/52467"/>
  	 *    <Link rel="describedby" type="application/rdf+xml" href="http://identi.ca/tkoski/foaf"/>
  	 *    <Link rel="http://salmon-protocol.org/ns/salmon-replies" href="http://identi.ca/main/salmon/user/52467"/>
  	 *    <Link rel="http://salmon-protocol.org/ns/salmon-mention" href="http://identi.ca/main/salmon/user/52467"/>
  	 *    <Link rel="magic-public-key" href="data:application/magic-public-key,RSA.oSdSbJ99WDC0zRUpk41bpI42FarMo-o6JxJKEeKCPSU1SW9kdXdAUPhWu0JVwdF5rDXWijXaOcdZ3utGwk0pmKxsX6MEQg54L4rfIzWZiHz9OUGgDx9R4tXpm38CXOGfpu4Sx2lmeYVxIii32P32EPJHyZN5Zi9Sr_8zSbXYnM8=.AQAB"/>
  	 *    <Link rel="http://ostatus.org/schema/1.0/subscribe" template="http://identi.ca/main/ostatussub?profile={uri}"/>
  	 * </XRD>
     * 
     * @param String $rawXml
     * @return LRDDXRD
     */
    public static function buildFromRawXML($rawXml) {
        $dom = new DOMDocument();
        if(@$dom->loadXML($rawXml)) {
            return self::buildFromDom($dom);
        }
        throw new Exception("Invalid raw XML data provided!");
    }
    
    public static function buildFromDom(DOMDocument $dom) {
        
        $xrd_element = $dom->getElementsByTagName('XRD')->item(0);
        if (!$xrd_element) {
            throw new Exception("Invalid DOM object for XRD, missing XRD root");
        }

        // Check for host-meta host
        $subject = $xrd_element->getElementsByTagName('Subject')->item(0);
        if (!$subject) { 
            throw new Exception("Invalid DOM object for XRD, missing subject value.");
        }    
        $subject = $subject->nodeValue;
        
        $links = "";
        foreach ($xrd_element->getElementsByTagName('Link') as $element) {
            $rel = $element->getAttribute('rel');
            if($rel) {
                $links[$rel]['href'] =  $element->getAttribute('href');
                $links[$rel]['type'] =  $element->getAttribute('type');  
            }
        }
        
        return new LRDDXRD($subject, $links);
    }
}